#ifndef __NET_CHANNEL_CORE_H__
#define __NET_CHANNEL_CORE_H__

#include "base/macro.h"
#include "comm/comm_def.h"

namespace weilin
{
	class RpcChannelCore : public boost::enable_shared_from_this<RpcChannelCore>
	{
		DISALLOW_COPY_AND_ASSIGN(RpcChannelCore);
	public:
		//accept
		RpcChannelCore(const ChannelType& channel_type, const uint32_t& channel_seq, const socket_shared_ptr& socket_sp, const bool& is_keep_alive, const uint32_t& ms_timeout, const call_back_shared_ptr& call_back_sp);

		//connected
		RpcChannelCore(const ChannelType& channel_type, const string& remote_ip, const uint16_t& port, const uint32_t& ms_timeout, const call_back_shared_ptr& call_back_sp);
		~RpcChannelCore();



		//client
		void AsyncConnect();
		void AsyncReConnect();
		void AsyncSendController(const controller_shared_ptr& controller_sp);
		bool IsBusy();

		//server
		void AsyncSendPacket(const packet_shared_ptr& packet_sp);
		const uint32_t& GetSeq();

		//recv
		void StartAsyncRecv();

		//get romote ipport
		const string& GetRemoteIpPort();

		//stop
		void Stop();
	private:

		//close
		void close(const bool& is_need_callback);

		//connect
		void statrtAsyncConnect();
		void handleAsyncConnectCb(uint32_t connect_seq, const boost::system::error_code& error);
		void handleAsyncConnectTimerCheck(const boost::system::error_code& error);
		void startAsyncReConnect();

		//send
		void asyncSendController(const controller_shared_ptr& controller_sp);
		void asyncSendPacket(const packet_shared_ptr& packet_sp);
		void asyncSendControllerTimeout(const controller_weak_ptr& controller_wp, const boost::system::error_code& ec);
		//system
		void startSendAsync();
		void handleSendAsyncCb(const packet_shared_ptr& packet_sp, const boost::system::error_code &err, std::size_t bytes_transferred);

		//receve
		void startRecvAsync();
		void handleRecvAsyncCb(const boost::system::error_code &err, std::size_t bytes_transferred);

		//server disconnect timer for disconnect
		void noKeepaliveTimer();
		void noKeepaliveTimerCb(const boost::system::error_code& err);

		//stop
		void stop(const wait_event_shared_ptr& event_sp);


	private:
		ChannelType m_channel_type;
		uint32_t m_channel_seq;
		string m_remote_server_name;

		boost::asio::io_service& m_io_service;
		socket_shared_ptr m_socket_sp;
		timer_shared_ptr m_timer_sp;
		channel_post_shared_ptr m_channel_post_sp;

		bool m_is_keep_alive;
		uint32_t m_ms_timeout;

		boost::asio::ip::tcp::endpoint m_endpoint;
		packet_shared_ptr m_recv_packet_sp;

		bool m_is_client;
		SocketStatus m_socket_status;
		bool m_is_sending;
		uint32_t m_connect_seq;
		string m_remote_ip_port;

		string m_once_recv_str;

		flow_status_shared_ptr m_flow_status_sp;

	};
}

#endif
